import { CodeGroup, FileName } from "@/components/forMdx";

export const metadata = {
  description: "FileStreams handle binary data in Jazz applications - think documents, audio files, and other non-text content."
};

# FileStreams

FileStreams handle binary data in Jazz applications - think documents, audio files, and other non-text content. They're essentially collaborative versions of `Blob`s that sync automatically across devices.

Use FileStreams when you need to:
- Distribute documents across devices
- Store audio or video files
- Sync any binary data between users

**Note:** For images specifically, Jazz provides the higher-level `ImageDefinition` abstraction which manages multiple image resolutions - see the [ImageDefinition documentation](/docs/core-concepts/covalues/imagedef) for details.

FileStreams provide automatic chunking when using the `createFromBlob` method, track upload progress, and handle MIME types and metadata.

In your schema, reference FileStreams like any other CoValue:

<FileName>schema.ts</FileName>
<CodeGroup>
```ts schema.ts
```
</CodeGroup>

## Creating FileStreams

There are two main ways to create FileStreams: creating empty ones for manual data population or creating directly from existing files or blobs.

### Creating from Blobs and Files

For files from input elements or drag-and-drop interfaces, use `createFromBlob`:

<CodeGroup>
```ts index.ts#FromBlob
```
</CodeGroup>

### Creating Empty FileStreams

Create an empty FileStream when you want to manually [add binary data in chunks](#writing-to-filestreams):

<CodeGroup>
```ts index.ts#Empty
```
</CodeGroup>

### Ownership

Like other CoValues, you can specify ownership when creating FileStreams.

<CodeGroup>
```ts index.ts#Ownership
```
</CodeGroup>

 See [Groups as permission scopes](/docs/permissions-and-sharing/overview) for more information on how to use groups to control access to FileStreams.

## Reading from FileStreams

`FileStream`s provide several ways to access their binary content, from raw chunks to convenient Blob objects.

### Getting Raw Data Chunks

To access the raw binary data and metadata:

<CodeGroup>
```ts index.ts#GetRaw
```
</CodeGroup>

By default, `getChunks()` only returns data for completely synced `FileStream`s. To start using chunks from a `FileStream` that's currently still being synced use the `allowUnfinished` option:

<CodeGroup>
```ts index.ts#GetIncomplete
```
</CodeGroup>

### Converting to Blobs

For easier integration with web APIs, convert to a `Blob`:

<CodeGroup>
```ts index.ts#GetAsBlob
```
</CodeGroup>

### Loading FileStreams as Blobs

You can directly load a `FileStream` as a `Blob` when you only have its ID:

<CodeGroup>
```ts index.ts#LoadAsBlob
```
</CodeGroup>

### Checking Completion Status

Check if a `FileStream` is fully synced:

<CodeGroup>
```ts index.ts#CheckSync
```
</CodeGroup>

## Writing to FileStreams

When creating a `FileStream` manually (not using `createFromBlob`), you need to manage the upload process yourself. This gives you more control over chunking and progress tracking.

### The Upload Lifecycle

`FileStream` uploads follow a three-stage process:

1. **Start** - Initialize with metadata
2. **Push** - Send one or more chunks of data
3. **End** - Mark the stream as complete

### Starting a `FileStream`

Begin by providing metadata about the file:

<CodeGroup>
```ts index.ts#ManualStart
```
</CodeGroup>

### Pushing Data

Add binary data in chunks - this helps with large files and progress tracking:

<CodeGroup>
```ts index.ts#AddChunks
```
</CodeGroup>

### Completing the Upload

Once all chunks are pushed, mark the `FileStream` as complete:

<CodeGroup>
```ts index.ts#Finalise
```
</CodeGroup>

## Subscribing to `FileStream`s

Like other CoValues, you can subscribe to `FileStream`s to get notified of changes as they happen. This is especially useful for tracking upload progress when someone else is uploading a file.

### Loading by ID

Load a `FileStream` when you have its ID:

<CodeGroup>
```ts index.ts#LoadById
```
</CodeGroup>

### Subscribing to Changes

Subscribe to a `FileStream` to be notified when chunks are added or when the upload is complete:

<CodeGroup>
```ts index.ts#SubscribeById
```
</CodeGroup>

### Waiting for Upload Completion

If you need to wait for a `FileStream` to be fully synchronized across devices:

<CodeGroup>
```ts index.ts#WaitForSync
```
</CodeGroup>

This is useful when you need to ensure that a file is available to other users before proceeding with an operation.
